`timescale 1ns/1ps

`include "code\source\P3\nco_fsk.v"

module test_nco_fsk;
initial begin
    $dumpfile("./release/test_nco_fsk.vcd");
    $dumpvars(0, test_nco_fsk);
end
// Generate clock
reg clk, clk2;
initial clk = 0;
always #1 clk = ~clk;

initial clk2 = 0;
always #200 clk2 = ~clk2;

// Input registers
reg reset, load, din, din_valid;
reg [31:0] fcw1;
reg [31:0] fcw2;
// Output wires
wire out_valid;
wire [11:0] out;
// TB Variable
wire [14:0] lut_addr;
wire [11:0] lut_data;
reg [11:0] lut_mem [0:32768];

initial begin
    $readmemb("D:/programming/verilog/Digital_Communication_SelfTest/code/test/P3/code_lut.txt", lut_mem);
end

assign lut_data = lut_mem[lut_addr];
// Tasks
task set_fcw(input [31:0] _fcw1, input [31:0] _fcw2);
    begin
        $display("set_fcw: %d %d", _fcw1, _fcw2);
        @(negedge clk);
        fcw1 = _fcw1;
        fcw2 = _fcw2;
        load = 1;
        @(negedge clk);
        load = 0;
    end
endtask

initial begin
    reset = 1;
    load = 0;
    fcw1 = 0;
    fcw2 = 0;
    din = 0;
    din_valid = 0;
    @(negedge clk);
    reset = 0;
    repeat(2) @(posedge  clk);

    set_fcw(100000000, 200000000);

    @(negedge clk);
    din_valid = 1;

    repeat(2000) @(posedge  clk);

    @(negedge clk);
    din_valid = 0;

    set_fcw(0, 0);
    repeat(1000) @(posedge  clk);
    // Exit the simulation
    $finish;
end

always@(posedge clk2) din = ~din;

integer i = 1;

always@(negedge clk) begin
    i <= i + 1;
    if (out_valid && i > 1000) begin
        $display("%d: %d", i, out);
    end
end

// Device under test (our adder)
nco_fsk dut (.rst_n(~reset), .clk(clk), .fcw1(fcw1), .fcw2(fcw2), .load(load), .out(out), .out_valid(out_valid), .din(din), .din_valid(din_valid), .lut_data(lut_data), .lut_addr(lut_addr));

endmodule
